home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d18
/
textf.arc
/
TEXTF.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-04-28
|
8KB
|
244 lines
{$R-,V-,I-,S-}
Unit textf;
{ -USES Nothing- }
(*********************************************************************
Fast disk file text reading operations.
This program is a OOP'd version of Don Strenczewilk's [72617,132]
RLINE package.
Modifications by Arthur Zatarain, C'serve 73417,525 09/25/89
This unit contains some fast reading routines designed to work with
standard ASCII disk files:
FOpen Open a file
FRead Read the next character
FReadLn Read the next string
FFilePos Return the current position in the file
FSeek Seek to any position
FClose Close a file
The RLINE unit uses about 600 bytes of your programs code space,
and 0 data.
**********************************************************************)
Interface
(*********************************************************************)
(*
An object of type RFrec is maintained by the TEXTF Unit and
contains information about the file handle, the buffer address, current
position in the file, size of the buffer, and current location in buffer:
*)
TYPE
{ Generic type which allows access to segment and offset of pointer }
SegOfsPtr = RECORD
CASE Boolean OF
True : (Pntr : Pointer);
False : (Ofst, Sgmnt : Word);
END;
RFrec = object
Handle : Word; { File handle }
BufPtr : SegOfsPtr; { BufOfs, BufSeg}
Bpo, { Current buffer position }
BSize, { Buffer size in bytes }
BLeft, { Bytes left in buffer to scan }
NBufs : Word; { Number of buffers read. = 0 if none. }
TotBytesInBuf : Word; { Total bytes that were read into current buffer.}
constructor init;
PROCEDURE FClose; virtual;
FUNCTION FSeek(FPo : LongInt) : Word; virtual;
function FOpen(Fn : STRING; { Name of file to open. }
DBSize : Word; { Size of buffer. 512 bytes minimum. }
VAR BufP) { Disk buffer to use. }
: Word; virtual;
{ String variable to read next line to. }
FUNCTION FReadLn(VAR S : STRING) : word; virtual;
FUNCTION FRead(VAR Ch : Char) { String variable to read next line to. }
: Word; virtual;
FUNCTION FFilePos : LongInt; virtual;
END; { rfrec object }
(*
All you need to know to use the RLINE routines is that you must declare a
variable of type RFrec somewhere.
Function FOpen
function FOpen(Fn : STRING; { Name of file to open. }
DBSize : Word; { Size of buffer. 512 bytes minimum. }
VAR BufP) { Disk buffer to use. }
: Word;
A file must first be successfully opened with a call to FOpen, before any of
the other routines are used.
A buffer must be declared to be passed to the FOpen function. There are no
restrictions on the location of the buffer, so it can be a global or local
variable, or allocated with New() or GetMem().
If successful:
Returns 0.
If failed:
Returns DOS error code if a DOS error occured,
or error 12 (Invalid File Access Code) if the buffer size is 0.
TRAPS:
If using a buffer allocated with New() or GetMem(), be sure to use the caret
after it for the BufP parameter. Ie. IF FOpen(RF, Fn, BSize, BufP^)...
Never call FOpen twice with the same RFrec variable without closing the old
one first.
EXAMPLE:
VAR
RF : RFrec;
Buffer : Array[1..2048] of Char;
Error : Word;
BEGIN
Error := FOpen(RF, 'HELLO.PAS', Sizeof(Buffer), Buffer);
If Error = 0
THEN Writeln('Success')
ELSE Writeln('Error: ', i);
...
--------------------------------------------------------------------------
Procedure FClose - When done with the file, it must be closed with a call to
FClose:
PROCEDURE FClose(VAR RF : RFrec);
Closes previously opened RFrec.
Returns nothing.
This procedure attempts to identify whether the file has been previously
opened before it attempts to ask DOS to close it. It does not attempt to
close the file if:
a) RF.BSize = 0. Function FOpen sets RF.BSize to 0 if DOS open failed.
or
b) RF.Handle < 5, in which case it would be a standard DOS handle, which
shouln't be closed.
TRAP: A problem that could occur with this scheme would be if (the file was
never even attempted to be opened by FOpen) AND (the handle = the handle of
a file that is currently opened somewhere else in the program).
----------------------------------------------------------------------
Function FReadLn
FReadLn - Reads a string of characters up to the next ^M, or ^Z <EOF>, or
the physical end of file, whichever comes first.
The maximum length of the string returned to caller is 255 characters. If
more than 255 characters are passed in the file before ^M or <EOF>, the
remaining characters are irretreivable.
FUNCTION FReadLn(VAR RF : RFrec; { Previously opened RFrec variable }
VAR S : STRING) { String variable to read next line to. }
: Word;
On success:
Returns 0.
S = next string read from file RF.Handle.
On failure:
returns either DOS error code,
or $FFFF if End of File
Works like a Turbo Readln(F, S); except:
(1) It works only with disk files.
(2) Only reads strings. ie. not integers, words, or any other type.
(3) It is much faster.
(4) Doesn't stop when a ^Z is encountered before end of file. If a ^Z
is encountered AT the end of file, it is stripped. Any ^Z's encountered
before the physical end of the file are passed on to the string.
----------------------------------------------------------------------
Function FRead - Reads the next character from the file:
}
FUNCTION FRead(VAR RF : RFrec; { Previously opened RFrec variable }
VAR Ch : Char) { String variable to read next line to. }
: Word;
{
Works the same as FReadLn but returns one character instead of a string.
All characters are passed on to Ch except if a ^Z is at end of file.
If successful:
Returns 0. Ch = next character in the file.
If failed:
Returns either DOS error code,
or $FFFF if End of File
----------------------------------------------------------------------
Function FFilePos - Returns current file position for use with FSeek.
FUNCTION FFilePos : LongInt;
Returns current file position. RF must have been previously opened.
If FFilePos is called before FOpen is called successfully, the results will
be meaningless.
----------------------------------------------------------------------
Function FSeek - Seeks to position FPo in previously opened RF.
FUNCTION FSeek(FPo : LongInt) : Word;
If successful, Returns 0
If failed, returns DOS error code.
To Reset the file, call RFSeek with FPo := 0. Ie. FSeek(RF,0);
On a normal ^M^J ascii file, FFilePos will most often return the position of
the ^J after a call to FReadLn. Because FReadLn strips leading ^J's, this
shouldn't be a problem. But, bear that in mind if using the FFilePos
results for your own untyped file routines.
*)
(****************************************************************************)
Implementation
(****************************************************************************)
{=================================================================}
{$L textf.OBJ} { EXTERNAL DECLARATIONS }
{ All PROCs are FAR }
FUNCTION rfrec.FOpen(Fn : STRING;
DBSize : Word;
VAR BufP) : Word; EXTERNAL;
FUNCTION rfrec.FReadLn(VAR S : STRING) : Word; EXTERNAL;
FUNCTION rfrec.FRead(VAR Ch : Char) : Word; EXTERNAL;
FUNCTION rfrec.FSeek(FPo : LongInt) : Word; EXTERNAL;
PROCEDURE rfrec.FClose; EXTERNAL;
{=================================================================}
FUNCTION rfrec.FFilePos : LongInt;
BEGIN
{ RF.NBufs is equal to 1 when there has been at least 1 buffer read. }
IF NBufs = 0 { If current buffer number = 0, nothing's been read. }
THEN FFilePos := 0
ELSE FFilePos := (LongInt(NBufs-1)*BSize)+(Bpo-BufPtr.Ofst);
END;
constructor rfrec.init;
begin
end;
end.